import bpy
import json
import os
from os import path
from bpy.types import Panel, Operator, PropertyGroup
from bpy.props import *
from .color_data import COLORS_PRESETS, refresh_custom_palettes  # 修改导入语句

#  加载预设色卡
def load_preset_colors(scene):
    if not hasattr(scene, 'preset_colors'):
        return

    try:
        scene.preset_colors.clear()
        # 获取当前选择的预设
        current_preset = scene.color_presets.preset_name
        for i, preset in enumerate(COLORS_PRESETS[current_preset]):
            item = scene.preset_colors.add()
            item.color = preset["color"]
            item.id = i
            item.name = preset["name"]
    except Exception as e:
        print(f"Error loading preset colors: {e}")
# 添加场景属性用于存储当前选择的预设
class SceneColorProperties(PropertyGroup):
    preset_name: EnumProperty(
        name="预设选择",
        description="选择颜色预设",
        items=[(key, key, "") for key in COLORS_PRESETS.keys()],
        default=0,  # 修改为索引值0，自动选择第一个预设
        update=lambda self, context: load_preset_colors(context.scene)
    )
# 添加重新加载预设的Operator
class CARD_OT_ReloadPreset(bpy.types.Operator):
    """重新加载当前选择的预设"""
    bl_idname = "card.reload_preset"
    bl_label = "重新加载预设"
    
    def execute(self, context):
        refresh_custom_palettes()  # 新增：强制刷新自定义调色板
        load_preset_colors(context.scene)
        return {'FINISHED'}
# 更改活动对象颜色
class CARD_OT_ChangeBaseColor(bpy.types.Operator):
    """Change the base color of the material"""
    bl_idname = "card.change_base_color"
    bl_label = "Change Base Color"

    color: FloatVectorProperty(
        name="Color",
        subtype='COLOR',
        default=(1.0, 1.0, 1.0, 1.0),
        size=4,
        min=0.0,
        max=1.0
    )

    def execute(self, context):
        obj = context.active_object
        if obj and obj.active_material:
            mat = obj.active_material
            mat.diffuse_color = self.color[:4]
            
            # 增加节点树存在性检查
            if mat.node_tree:
                for node in mat.node_tree.nodes:
                    for input in node.inputs:
                        if isinstance(input, bpy.types.NodeSocketColor):
                            input.default_value = self.color
        return {'FINISHED'}

    def invoke(self, context, event):
        return self.execute(context)
# 定义颜色属性组
class PresetColorPropertyGroup(PropertyGroup):
    """专门用于存储预设颜色的属性组"""
    id: IntProperty(name="ID", default=-1)
    name: StringProperty(name="Preset Name", default="Preset")
    color: FloatVectorProperty(
        name="Preset Colors",
        subtype='COLOR',
        size=4,
        min=0.0,
        max=1.0,
        default=(1.0, 1.0, 1.0, 1.0)
    )

class CustomColorPropertyGroup(PropertyGroup):
    """专门用于存储自定义颜色的属性组"""
    id: IntProperty(name="ID", default=-1)
    name: StringProperty(name="Custom Name", default="Custom")
    color: FloatVectorProperty(
        name="Custom Colors",
        subtype='COLOR',
        size=4,
        min=0.0,
        max=1.0,
        default=(1.0, 1.0, 1.0, 1.0)
    )

class CurrentColorPropertyGroup(PropertyGroup):
    """专门用于存储当前选中颜色的属性组"""
    color: FloatVectorProperty(
        name="Current Color",
        subtype='COLOR',
        size=4,
        min=0.0,
        max=1.0,
        default=(1.0, 1.0, 1.0, 1.0)
    )

# 预设调色板
class CARD_PT_PresetColors(bpy.types.Panel):
    """预设调色板"""
    bl_label = "预设调色板"
    bl_idname = "CARD_PT_preset_colors"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Material'

    def draw(self, context):
        layout = self.layout
        box = layout.box()
        
        # 添加预设选择下拉菜单
        row = box.row()
        row.prop(context.scene.color_presets, "preset_name", text="")
        
        # 添加重新加载按钮
        reload_op = row.operator("card.reload_preset", text="", icon='FILE_REFRESH')
        
        box.label(text="预设颜色")

        # 确保预设颜色已加载
        if not hasattr(context.scene, 'preset_colors') or len(context.scene.preset_colors) == 0:
            box.label(text="正在加载预设颜色...")
            load_preset_colors(context.scene)  # 尝试重新加载
            return

        # 设置 grid_flow 的列数和 ui_units_x
        flow = box.grid_flow(row_major=True, columns=4, even_columns=True, even_rows=False, align=True)
        
        for item in context.scene.preset_colors:
            col = flow.column(align=True)
            
            # 颜色块区域
            color_row = col.row(align=True)
            color_row.enabled = True  # 禁用颜色选择器
            color_row.prop(
                item,
                "color",
                text="",
                emboss=True,  # 移除浮雕效果以使颜色块成为纯色正方形
                icon='NONE'  # 移除图标以使颜色块成为正方形
            )
            color_row.scale_x = 1.0  # 设置为正方形
            color_row.scale_y = 1.0
            
            # 应用按钮区域
            button_row = col.row(align=True)
            op = button_row.operator("card.change_base_color", text=item.name)
            op.color = item.color

# 自定义调色板
class CARD_PT_CustomColors(bpy.types.Panel):
    """自定义调色板"""
    bl_label = "自定义调色板"
    bl_idname = "CARD_PT_custom_colors"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Material'


    def draw(self, context):
        scene = context.scene
        layout = self.layout
        
        # 导入导出功能保持原样
        box = layout.box()
        box.label(text="调色板管理")
        row = box.row()
        row.operator("card.export_colors", text="导出")
        row.operator("card.import_colors", text="导入")
        
        # 颜色集合初始化检查保持原样
        if not hasattr(scene, 'custom_colors'):
            layout.label(text="正在初始化颜色...")
            return
        
        # 添加自定义颜色区域保持原样
        box = layout.box()
        box.prop(scene.current_base_color, "color", text="当前颜色")
        box.operator("card.add_custom_color", text="添加为自定义颜色")
        
        # 修改颜色显示部分
        box = layout.box()
        box.label(text="自定义颜色")
        
        # 使用grid_flow布局对齐预设面板样式
        flow = box.grid_flow(row_major=True, columns=4, even_columns=True, align=True)
        
        for i, item in enumerate(scene.custom_colors):
            col = flow.column(align=True)
            
            # 颜色块区域 - 与预设面板相同样式
            color_row = col.row(align=True)
            color_row.enabled = True  # 禁用编辑功能
            color_row.prop(
                item,
                "color",
                text="",
                emboss=True,
                icon='NONE'
            )
            color_row.scale_x = 1.0
            color_row.scale_y = 1.0
            
            # 应用按钮区域 - 与预设面板相同样式
            button_row = col.row(align=True)
            op = button_row.operator("card.change_base_color", text=item.name)
            op.color = item.color

# 添加自定义颜色
class CARD_OT_AddCustomColor(bpy.types.Operator):
    """Add current color to custom presets"""
    bl_idname = "card.add_custom_color"
    bl_label = "添加自定义颜色"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):
        scene = context.scene
        new_color = scene.current_base_color.color[:]

        # 检查是否已存在该颜色
        exists = any(tuple(c.color) == tuple(new_color) for c in scene.custom_colors)
        if exists:
            self.report({'WARNING'}, "颜色已存在")
            return {'CANCELLED'}

        # 明确添加到自定义颜色集合
        item = scene.custom_colors.add()
        item.name = f"自定义颜色 {len(scene.custom_colors)}"
        item.color = new_color
        item.id = len(scene.custom_colors) - 1
        
        self.report({'INFO'}, "颜色已添加到自定义色板")
        return {'FINISHED'}

# 导出颜色到JSON文件
class CARD_OT_ExportColors(bpy.types.Operator):
    """导出自定义颜色到JSON文件"""
    bl_idname = "card.export_colors"
    bl_label = "导出颜色"
    bl_options = {'REGISTER', 'UNDO'}
    
    filepath: bpy.props.StringProperty(
        subtype="FILE_PATH",
        default="色卡.json"
    )
    filename_ext = ".json"
    filter_glob: StringProperty(
        default="*.json",
        options={'HIDDEN'}
    )
    
    # 缓存插件目录路径
    _plugin_dir = None
    
    @classmethod
    def get_plugin_dir(cls):
        if cls._plugin_dir is None:
            cls._plugin_dir = path.join(path.dirname(path.abspath(__file__)), "CustomPalette")
            if not path.exists(cls._plugin_dir):
                os.makedirs(cls._plugin_dir)
        return cls._plugin_dir

    def invoke(self, context, event):
        # 使用缓存的插件目录路径
        self.filepath = path.join(self.get_plugin_dir(), "色卡.json")
        context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}

    def execute(self, context):
        scene = context.scene
        colors = []
        
        # 收集所有自定义颜色数据
        for color in scene.custom_colors:
            colors.append({
                "name": color.name,
                "color": list(color.color),
                "id": color.id
            })
        
        try:
            # 写入JSON文件
            with open(self.filepath, 'w', encoding='utf-8') as f:
                json.dump(colors, f, ensure_ascii=False, indent=4)
            self.report({'INFO'}, f"颜色已导出到 {self.filepath}")
        except Exception as e:
            self.report({'ERROR'}, f"导出失败: {str(e)}")
            return {'CANCELLED'}
        
        return {'FINISHED'}
    
# 从JSON文件导入颜色
class CARD_OT_ImportColors(bpy.types.Operator):
    """从JSON文件导入自定义颜色"""
    bl_idname = "card.import_colors"
    bl_label = "导入颜色"
    bl_options = {'REGISTER', 'UNDO'}
    
    filepath: bpy.props.StringProperty(subtype="FILE_PATH")
    filename_ext = ".json"
    filter_glob: StringProperty(
        default="*.json",
        options={'HIDDEN'}
    )
    
    # 共享同一个缓存插件目录路径
    get_plugin_dir = CARD_OT_ExportColors.get_plugin_dir

    def invoke(self, context, event):
        # 使用缓存的插件目录路径
        self.filepath = path.join(self.get_plugin_dir(), "色卡.json")
        context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}

    def execute(self, context):
        scene = context.scene
        
        try:
            # 读取JSON文件
            with open(self.filepath, 'r', encoding='utf-8') as f:
                colors = json.load(f)
            
            # 清空现有颜色
            scene.custom_colors.clear()
            
            # 添加导入的颜色
            for color_data in colors:
                item = scene.custom_colors.add()
                item.name = color_data["name"]
                item.color = color_data["color"]
                item.id = color_data["id"]
            
            self.report({'INFO'}, f"从 {self.filepath} 导入 {len(colors)} 个颜色")
        except Exception as e:
            self.report({'ERROR'}, f"导入失败: {str(e)}")
            return {'CANCELLED'}
        
        return {'FINISHED'}



# 注册/注销
# 在文件末尾添加导出属性列表
export_properties = [
    ("preset_colors", bpy.props.CollectionProperty(type=PresetColorPropertyGroup)),  # 预设颜色集合
    ("custom_colors", bpy.props.CollectionProperty(type=CustomColorPropertyGroup)),  # 自定义颜色集合
    ("current_base_color", bpy.props.PointerProperty(type=CurrentColorPropertyGroup)),
    ("color_presets", bpy.props.PointerProperty(type=SceneColorProperties))
]

# 在文件末尾添加导出类列表
export_classes = [
    PresetColorPropertyGroup,
    CustomColorPropertyGroup,
    CurrentColorPropertyGroup,
    CARD_OT_ChangeBaseColor,
    CARD_OT_AddCustomColor,
    CARD_OT_ExportColors,
    CARD_OT_ImportColors,
    CARD_PT_PresetColors,
    CARD_PT_CustomColors,
    SceneColorProperties,
    CARD_OT_ReloadPreset
]

if __name__ == "__main__":
    register()